package com.im.util;

import java.io.BufferedReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.im.service.dto.BaseException;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.DefaultValueProcessor;
import net.sf.json.util.JSONUtils;
import net.sf.json.util.PropertyFilter;

public class JsonUtil {
	
	private static final Logger logger = LogManager.getLogger(JsonUtil.class);
	/*
	 * 获取httpservice中的json格式入参
	 */
	public static String getJsonFromRequest(HttpServletRequest request,
			HttpServletResponse response) {
		StringBuffer jb = new StringBuffer();
		String line = null;
		try {
			BufferedReader reader = request.getReader();
			while ((line = reader.readLine()) != null){
				jb.append(line);
			}
		} catch (Exception e) {
			// 读取服务器流异常
		}
		JSONObject jsonObject = null;
		try {
			jsonObject = JSONObject.fromObject(jb.toString());
		} catch (Exception e) {
			// 数据格式转换异常
		}

		return jsonObject.toString();
	}
	
	public static Map<String, Object> getIpFromRequest(HttpServletRequest request,
			HttpServletResponse response){
		Map<String, Object> resultMap = new HashMap<String, Object>();
		
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}	
//		LookupService cl = null;
//		try {
//			cl = new LookupService("D:\\MB\\GeoIP.dat",LookupService.GEOIP_MEMORY_CACHE);
//			System.out.println(cl.getCountry("180.164.229.229").getName());
//			System.out.println(cl.getCountry("180.164.229.229").getCode());
//			cl.close();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		resultMap.put("Ip", ip);
//		resultMap.put("name", cl.getCountry(ip).getName());
//		resultMap.put("code", cl.getCountry(ip).getCode());
		return resultMap;
	}
	//处理number的null与日期类
	public final static JsonConfig DEFAULT_AND_DATTE_JSONCONF = createDefaultAndDateJsonConfig(false);
	//处理number的null与日期类，同时处理过滤null
	public final static JsonConfig FILTENULL_AND_DATTE_JSONCONF = createDefaultAndDateJsonConfig(true);
	/**
	 * 处理全部
	 * @return
	 */
	public static JsonConfig createDefaultAndDateJsonConfig(boolean ifFilteNull){
		JsonConfig conf = new JsonConfig();
		if(!ifFilteNull) registerDefaultNullValueProcessor(conf);
		registerDateValueProcessor(conf);
		if(ifFilteNull) registerNullFilter(conf);
		return conf;
	}
	/**
	 * 注册json的处理类
	 * @param conf
	 */
	public static void registerDefaultNullValueProcessor(JsonConfig conf){
		conf.registerDefaultValueProcessor(Number.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(AtomicInteger.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(BigDecimal.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(BigInteger.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(Byte.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(Double.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(Float.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(Integer.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(Long.class,new DefaultNullValueProcessor());
		conf.registerDefaultValueProcessor(Short.class,new DefaultNullValueProcessor());		
	}
	/**
	 * null空值特殊处理类
	 * @author zhaoxin
	 *
	 */
	public static class DefaultNullValueProcessor implements DefaultValueProcessor{
		  public Object getDefaultValue(Class type){
	            return JSONNull.getInstance();
	        }
	}
	/**
	 * 处理日期类转换
	 * @param conf
	 */
	public static void registerDateValueProcessor(JsonConfig conf){
//		conf.registerJsonValueProcessor(java.util.Date.class,
//				new JsonDateValueProcessor());
	}
	/**
	 * 注册空过滤器
	 * */
	public static void registerNullFilter(JsonConfig conf){
		PropertyFilter filter = new PropertyFilter() {            
    	public boolean apply(Object object, String fieldName, Object fieldValue) {
	    		//仅过滤NULL的属性值
	    		return null == fieldValue/*||"".equals(fieldValue.toString())*/;
    		}
    	}; 
    	conf.setJsonPropertyFilter(filter);
	}
	
	/**
	 * 从JSONObject获取String值
	 * 
	 * @param jsonObj
	 * @param key
	 */
	public static String getStringFromJSON(JSONObject jsonObj,String key,String errorMsg){
		checkJSONObjectNullErrorThrow(jsonObj,new StringBuffer(errorMsg).append("从JSON：").append(jsonObj).append(
		        "中获取String型的[").append(key).append("]失败，原因是：JSON本身为Null").toString());
		if(!jsonObj.containsKey(key)){
			return null;
		}
		try{
			String s = jsonObj.getString(key);
			if("null".equals(s) || "".equals(s)){
				s = null;
			}
			return s;
		}catch(Exception e){
			throw new BaseException(new StringBuffer().append(errorMsg)
			        .append("从JSON：").append(jsonObj).append("中获取String型[")
			        .append(key).append("]失败，原因是：").append(e.getMessage()).toString());
		}
	}
	
	/**
	 * 从JSONObject获取Long值
	 * 
	 * @param jsonObj
	 * @param key
	 */
	public static Long getLongFromJSON(JSONObject jsonObj,String key,String errorMsg){
		checkJSONObjectNullErrorThrow(jsonObj,new StringBuffer(errorMsg).append("从JSON：").append(jsonObj).append(
		        "中获取Long型的[").append(key).append("]失败，原因是：JSON本身为Null").toString());
		if(!jsonObj.containsKey(key) || "".equals(jsonObj.getString(key)) || "null".equals(jsonObj.getString(key))){
			return null;
		}
		try{
			return jsonObj.getLong(key);
		}catch(Exception e){
			throw new BaseException(new StringBuffer().append(errorMsg)
			        .append("从JSON：").append(jsonObj).append("中获取Long型[").append(key).append("]失败，原因是：").append(
			                e.getMessage()).toString());
		}
	}
	
	/**
	 * 从JSONObject获取Double值
	 * 
	 * @param jsonObj
	 * @param key
	 */
	public static Double getDoubleFromJSON(JSONObject jsonObj,String key,String errorMsg){
		checkJSONObjectNullErrorThrow(jsonObj,new StringBuffer(errorMsg).append("从JSON：").append(jsonObj).append(
		        "中获取Long型的[").append(key).append("]失败，原因是：JSON本身为Null").toString());
		if(!jsonObj.containsKey(key) || "".equals(jsonObj.getString(key)) || "null".equals(jsonObj.getString(key))){
			return null;
		}
		try{
			return jsonObj.getDouble(key);
		}catch(Exception e){
			throw new BaseException(new StringBuffer().append(errorMsg)
			        .append("从JSON：").append(jsonObj).append("中获取Long型[").append(key).append("]失败，原因是：").append(
			                e.getMessage()).toString());
		}
	}
	
	/**
	 * 从JSONObject获取Long值
	 * 
	 * @param jsonObj
	 * @param key
	 */
	public static Integer getIntegerFromJSON(JSONObject jsonObj,String key,String errorMsg){
		checkJSONObjectNullErrorThrow(jsonObj,new StringBuffer(errorMsg).append("从JSON：").append(jsonObj).append(
		        "中获取Long型的[").append(key).append("]失败，原因是：JSON本身为Null").toString());
		if(!jsonObj.containsKey(key) || "".equals(jsonObj.getString(key)) || "null".equals(jsonObj.getString(key))){
			return null;
		}
		try{
			return jsonObj.getInt(key);
		}catch(Exception e){
			throw new BaseException(new StringBuffer().append(errorMsg)
			        .append("从JSON：").append(jsonObj).append("中获取Long型[").append(key).append("]失败，原因是：").append(
			                e.getMessage()).toString());
		}
	}
	
	public static void checkJSONObjectNullErrorThrow(JSONObject jsonObj,String errorMsg){
		if(jsonObj == null){
			throw new BaseException(errorMsg);
		}
	}
	
	public static HashMap<String,Object>  getMap(String jsonString) {
		setDataFormat2JAVA();
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		HashMap<String,Object> map = new HashMap<String,Object>();
		for (Iterator iter = jsonObject.keys(); iter.hasNext();) {
			String key = (String) iter.next();
			map.put(key, jsonObject.get(key));
		}
		return map;
	}
	private static void setDataFormat2JAVA() {
		// 设定日期转换格式
		JSONUtils.getMorpherRegistry().registerMorpher(
				new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss",
						"yyyy-MM-dd" }));
	}
	
	public static JSONObject decryptMsg(String jsonObject) {	
		String json = JSONObject.fromObject(jsonObject).getString("encryptMsg");
		JSONObject result = null;
		try {
//			System.out.println(AES.Decrypt(json));
//			result = JSONObject.fromObject(AES.Decrypt(json));
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return result;
	}
	
	/**
	 * 
	 * 校验字符串是否符合JSON格式. 
	 * @param json
	 * @author xuwb
	 */
	public static boolean jsonValidate(String json) {
		if (StringUtils.isBlank(json)) {
			return false;
		}
		try {
			JSONObject.fromObject(json);
			return true;
		} catch (Exception e) {
			logger.error(new StringBuffer().append("字符串： ").append(json).append("不符合JSON格式").toString());
			return false;
		}
	}
	
	/**
	 * 从JSONObject获取String值，null也抛异常
	 * 
	 * @param jsonObj
	 * @param key
	 */
	public static String getNotNullStringFromJSON(JSONObject jsonObj, String key, String errorMsg) {
		checkJSONObjectNullErrorThrow(jsonObj, new StringBuffer(errorMsg).append("从JSON：").append(jsonObj)
				.append("中获取String型的[").append(key).append("]失败，原因是：JSON本身为Null").toString());
		if (!jsonObj.containsKey(key) || "".equals(jsonObj.getString(key)) || "null".equals(jsonObj.getString(key))) {
			throw new BaseException(new StringBuffer().append(errorMsg).append("从JSON：").append(jsonObj)
					.append("中获取非NUll的String型[").append(key).append("]失败，原因是：不存在该属性或者值为NULL").toString());
		}
		try {
			return jsonObj.getString(key);
		} catch (Exception e) {
			throw new BaseException(new StringBuffer().append(errorMsg).append("从JSON：").append(jsonObj)
					.append("中获取String型的[").append(key).append("]失败，原因是：").append(e.getMessage()).toString());
		}
	}
	
	/**
	 * 
	 * 递归获取json中指定key的第一个值以String形式输出. 
	 * @param jsonString
	 * @param key
	 * @return
	 * @author xuwb
	 */
	public static String obtainValueFromJsonObject(String jsonString,String key){
		String defaultResult = "";
		if(!jsonValidate(jsonString)){
			return defaultResult;
		}
		JSONObject json = JSONObject.fromObject(jsonString);
		if(json.containsKey(key)){
			defaultResult = json.getString(key);
			return defaultResult;
		}
		Iterator iterator = json.keys();
		while (iterator.hasNext() && "".equals(defaultResult)){
			String jsonKey = (String) iterator.next();
			if(!json.containsKey(key)){
				Object object = json.get(jsonKey);
				if (object instanceof JSONObject) {
					JSONObject subJson = (JSONObject) object;
					defaultResult = obtainValueFromJsonObject(subJson.toString(),key);
				}
				if (object instanceof JSONArray) {
					JSONArray array = (JSONArray) object;
					for (Object subObj : array) {
						JSONObject subJson = (JSONObject) subObj;
						defaultResult = obtainValueFromJsonObject(subJson.toString(),key);
					}
				}
			}
		}
		
		return defaultResult;
	}

	/**
	 * 从一个JSON 对象字符格式中得到一个java对象
	 * @param jsonString
	 * @param beanCalss
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T jsonToBean(String jsonString, Class<T> beanCalss) {
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		T bean = (T) JSONObject.toBean(jsonObject, beanCalss);

		return bean;

	}
	
	@SuppressWarnings("unchecked")
	public static <T> T jsonToBean(String jsonString, Class<T> beanCalss, Map classMap) {
		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		T bean = (T) JSONObject.toBean(jsonObject, beanCalss, classMap);

		return bean;

	}
	
	/**
	 * 
	 * 递归获取json中指定key的所有value. 
	 * @param jsonString
	 * @param key
	 * @return
	 * @author P_P
	 */
	public static List<String> obtainAllKeyValueFromJsonObject(String jsonString,String key){
		List<String> defaultList = new ArrayList<String>();
		if(!jsonValidate(jsonString)){
			return defaultList;
		}
		JSONObject json = JSONObject.fromObject(jsonString);
		if(json.containsKey(key)){
			defaultList.add(json.getString(key));
		}
		Iterator iterator = json.keys();
		while (iterator.hasNext()){
			String jsonKey = (String) iterator.next();
				Object object = json.get(jsonKey);
				if (object instanceof JSONObject) {
					JSONObject subJson = (JSONObject) object;
					defaultList.addAll(obtainAllKeyValueFromJsonObject(subJson.toString(),key));
				}
				if (object instanceof JSONArray) {
					JSONArray array = (JSONArray) object;
					for (Object subObj : array) {
						JSONObject subJson = (JSONObject) subObj;
						defaultList.addAll(obtainAllKeyValueFromJsonObject(subJson.toString(),key));
					}
				}
		}
		
		return defaultList;
	}

	/**
	 * Json字符串转类对象
	 * @param jsonstr
	 * @param clz
	 * @return
	 */
	public static Object jsonstrToBeanObj(String jsonstr,Class<?> clz){
		try {
			ObjectMapper mapper = new ObjectMapper();
			return mapper.readValue(jsonstr,clz);
		}catch (Exception e){
			e.printStackTrace();
			logger.error(e);
			return  null;
		}
	}
	
}
